
#include "container/queue.h"
#include <stdio.h>

#include "unity.h"

void test_QueueInit(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));
    TEST_ASSERT_EQUAL_PTR(buf, queue.pBuf);
    TEST_ASSERT_EQUAL_UINT(sizeof(int), queue.itemSize);
    TEST_ASSERT_EQUAL_UINT(sizeof(buf) / sizeof(int), queue.limit);
    TEST_ASSERT_EQUAL_UINT(0, queue.wIdx);
    TEST_ASSERT_EQUAL_UINT(0, queue.rIdx);
    TEST_ASSERT_TRUE(queue.isEmpty);
}

void test_QueueEmpty(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));
    TEST_ASSERT_TRUE(cotQueue_Empty(&queue));

    int data = 42;
    cotQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_FALSE(cotQueue_Empty(&queue));
}

void test_QueueFull(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));
    TEST_ASSERT_FALSE(cotQueue_Full(&queue));

    int data = 42;

    for (int i = 0; i < sizeof(buf) / sizeof(int); i++)
    {
        cotQueue_Push(&queue, &data, sizeof(data));
    }

    TEST_ASSERT_TRUE(cotQueue_Full(&queue));
}

void test_QueueSize(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));
    TEST_ASSERT_EQUAL_UINT(0, cotQueue_Size(&queue));

    int data = 42;
    cotQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_EQUAL_UINT(1, cotQueue_Size(&queue));
}

void test_QueueFront(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));

    int data = 42;
    cotQueue_Push(&queue, &data, sizeof(data));
    int *pData = (int *)cotQueue_Front(&queue);
    TEST_ASSERT_EQUAL_INT(data, *pData);
}

void test_QueueBack(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));

    int data = 42;
    cotQueue_Push(&queue, &data, sizeof(data));
    int *pData = (int *)cotQueue_Back(&queue);
    TEST_ASSERT_EQUAL_INT(data, *pData);
}

void test_QueuePush(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));

    int data = 42;
    int ret = cotQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_EQUAL_INT(0, ret);
    TEST_ASSERT_EQUAL_UINT(1, cotQueue_Size(&queue));
}

void test_QueuePop(void)
{
    uint8_t buf[10];
    cotQueue_t queue;

    cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int));
    int data = 42;
    cotQueue_Push(&queue, &data, sizeof(data));

    cotQueue_Pop(&queue);
    TEST_ASSERT_TRUE(cotQueue_Empty(&queue));
}

void test_QueueSwap(void)
{
    uint8_t buf1[10];
    uint8_t buf2[10];
    cotQueue_t queue1, queue2;

    cotQueue_Init(&queue1, buf1, sizeof(buf1), sizeof(int));
    cotQueue_Init(&queue2, buf2, sizeof(buf2), sizeof(int));

    int data1 = 1, data2 = 2;

    cotQueue_Push(&queue1, &data1, sizeof(data1));
    cotQueue_Push(&queue1, &data2, sizeof(data2));

    cotQueue_Swap(&queue1, &queue2);

    int *pData = (int *)cotQueue_Front(&queue2);
    TEST_ASSERT_EQUAL_INT(data1, *pData);
    cotQueue_Pop(&queue2);

    pData = (int *)cotQueue_Front(&queue2);
    TEST_ASSERT_EQUAL_INT(data2, *pData);
    cotQueue_Pop(&queue2);

    TEST_ASSERT_TRUE(cotQueue_Empty(&queue2));
}

void test_QueueSwapEmpty(void)
{
    uint8_t buf1[10];
    uint8_t buf2[10];
    cotQueue_t queue1, queue2;

    cotQueue_Init(&queue1, buf1, sizeof(buf1), sizeof(int));
    cotQueue_Init(&queue2, buf2, sizeof(buf2), sizeof(int));

    cotQueue_Swap(&queue1, &queue2);

    TEST_ASSERT_TRUE(cotQueue_Empty(&queue1));
    TEST_ASSERT_TRUE(cotQueue_Empty(&queue2));
}

void test_QueueSwapNonEmptyAndEmpty(void)
{
    uint8_t buf1[10];
    uint8_t buf2[10];
    cotQueue_t queue1, queue2;

    cotQueue_Init(&queue1, buf1, sizeof(buf1), sizeof(int));
    cotQueue_Init(&queue2, buf2, sizeof(buf2), sizeof(int));

    int data1 = 1, data2 = 2;

    cotQueue_Push(&queue1, &data1, sizeof(data1));
    cotQueue_Push(&queue1, &data2, sizeof(data2));

    cotQueue_Swap(&queue1, &queue2);

    TEST_ASSERT_TRUE(cotQueue_Empty(&queue1));
    TEST_ASSERT_FALSE(cotQueue_Empty(&queue2));

    TEST_ASSERT_EQUAL_UINT(0, cotQueue_Size(&queue1));
    TEST_ASSERT_EQUAL_UINT(2, cotQueue_Size(&queue2));
}



int test_Queue(void)
{
    UNITY_BEGIN();  // 初始化 Unity 测试框架

    RUN_TEST(test_QueueInit);
    RUN_TEST(test_QueueEmpty);
    RUN_TEST(test_QueueFull);
    RUN_TEST(test_QueueSize);
    RUN_TEST(test_QueueFront);
    RUN_TEST(test_QueueBack);
    RUN_TEST(test_QueuePush);
    RUN_TEST(test_QueuePop);
    RUN_TEST(test_QueueSwap);

    RUN_TEST(test_QueueSwapEmpty);
    RUN_TEST(test_QueueSwapNonEmptyAndEmpty);
    

    UNITY_END();  // 结束测试

    return 0;
}